package com.jmemoir.safe.paramsattack.filter;

import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.jmemoir.common.dto.Result;
import com.jmemoir.safe.paramsattack.wrapper.XssAndSqRequestWrapper;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Objects;

/**
 * 自定义防止 Xss/SQL 过滤器
 *
 * @author Tellsea
 * @date 2023/8/14
 */
@Component
public class XssAndSqlFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        XssAndSqRequestWrapper xssRequest = new XssAndSqRequestWrapper(httpRequest);

        if ("POST".equalsIgnoreCase(httpRequest.getMethod())) {
            String param = getPostParams(httpRequest);
            if (!Objects.isNull(param) && xssRequest.checkXSSAndSql(param)) {
                ServletUtil.write(httpResponse, JSONUtil.toJsonStr(Result.fail("您所访问的页面请求中有违反安全规则元素存在，拒绝访问!")), "application/json;charset=UTF-8");
                return;
            }
        }
        if (xssRequest.checkParameter()) {
            ServletUtil.write(httpResponse, JSONUtil.toJsonStr(Result.fail("您所访问的页面请求中有违反安全规则元素存在，拒绝访问!")), "application/json;charset=UTF-8");
            return;
        }
        chain.doFilter(xssRequest, httpResponse);
    }

    private String getPostParams(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        return sb.toString();
    }
}
